#ifndef __UPGRADER_SERVER_H__
#define __UPGRADER_SERVER_H__

#include <map>
#include <mutex>
#include <functional>
#include "Util/util.h"
#include "Util/File.h"
#include "jsoncpp/json.h"
#include "Network/Buffer.h"

class UpgraderServer //: public Fdt::make_shared_base<Config>
{
public:
	using ConfigFunc = std::function<bool(Json::Value &, int &result)>;
	static UpgraderServer *instance()
	{
		if(s_UpgraderServer == nullptr)
		{
			s_UpgraderServer = new UpgraderServer();
		}
		return s_UpgraderServer;
	}

	~UpgraderServer(){}

	void RegistRPC();

	bool Setup(const Json::Value &request, const Fdt::BufferMap::Ptr &inMap, Json::Value &response, Fdt::BufferMap::Ptr &outBuffer);

	bool Upgrade(const Json::Value &request, const Fdt::BufferMap::Ptr &inMap, Json::Value &response, Fdt::BufferMap::Ptr &outBuffer);
	
	bool Progress(const Json::Value &request, const Fdt::BufferMap::Ptr &inMap, Json::Value &response, Fdt::BufferMap::Ptr &outBuffer);

	bool Version(const Json::Value &request, const Fdt::BufferMap::Ptr &inMap, Json::Value &response, Fdt::BufferMap::Ptr &outBuffer);

	bool CloudUpgrade(const std::string& url);
	bool CloudUpgrade(const Json::Value &request, const Fdt::BufferMap::Ptr &inMap, Json::Value &response, Fdt::BufferMap::Ptr &outBuffer);

	bool CloudProgress(const Json::Value &request, const Fdt::BufferMap::Ptr &inMap, Json::Value &response, Fdt::BufferMap::Ptr &outBuffer);

	int CloudProgress();
protected:
	UpgraderServer();

private:
	bool verifySetup(const Json::Value &request);
	bool verifyUpgrade(const Json::Value &request, std::string &str_err);

	bool checkInternetPing(void);
private:
	static UpgraderServer *			s_UpgraderServer;
	std::recursive_mutex			_mutex;

	std::string						_upType;
	std::string						_fileName;
	std::string						_md5;
	std::string						_name;

	size_t							_total = 0;
//	size_t							_bytes = 0;
	size_t							_index = 0;
	size_t							_size  = 0;
	size_t							_pos   = 0;
//	size_t							_slice = 0;
	int                             _progress = 0;

//	Fdt::File						_file;
	std::map<std::string, std::map<void *, ConfigFunc>> _setMap;
	std::map<std::string, std::map<void *, ConfigFunc>> _verifyMap;

};




#endif
